package com.rzjm.exercise.sys.system.menu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.rzjm.exercise.common.base.service.impl.BaseServiceImpl;
import com.rzjm.exercise.common.utils.BuildTree;
import com.rzjm.exercise.common.utils.RightsHelper;
import com.rzjm.exercise.sys.system.menu.dao.MenuDao;
import com.rzjm.exercise.sys.system.menu.domain.MenuDO;
import com.rzjm.exercise.sys.system.menu.service.MenuService;
import com.rzjm.exercise.sys.system.role.dao.RoleDao;
import com.rzjm.exercise.sys.system.role.domain.RoleDO;
import com.rzjm.exercise.sys.system.user.dao.UserDao;
import com.rzjm.exercise.sys.system.user.domain.UserDO;
import com.rzjm.exercise.sys.vo.Tree;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
@Transactional(readOnly = true,rollbackFor = Exception.class)
public class MenuServiceImpl extends BaseServiceImpl<MenuDao, MenuDO> implements MenuService {
	@Resource
	MenuDao menuMapper;
	@Resource
	RoleDao roleDao;
	@Resource
	UserDao userDao;
	/**
	 * @param
	 * @return 树形菜单
	 */
	@Cacheable
	@Override
	public Tree<MenuDO> getSysMenuTree(Integer id) {
		List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
		QueryWrapper<MenuDO> qw = new QueryWrapper<>();
		qw.orderByAsc("order_num");
		qw.eq("show_type",1)
				.and(wrapper -> wrapper.eq("menu_type", 0).or().eq("menu_type", 1));
		List<MenuDO> menuDOs = menuMapper.selectList(qw);
		for (MenuDO sysMenuDO : menuDOs) {
			Tree<MenuDO> tree = new Tree<MenuDO>();
			tree.setId(sysMenuDO.getMenuId().toString());
			tree.setParentId(sysMenuDO.getParentId().toString());
			tree.setText(sysMenuDO.getName());
			tree.setMenuType(sysMenuDO.getMenuType());
			Map<String, Object> attributes = new HashMap<>(16);
			attributes.put("url", sysMenuDO.getUrl());
			attributes.put("icon", sysMenuDO.getIcon());
			tree.setAttributes(attributes);
			trees.add(tree);
		}
		// 默认顶级菜单为０，根据数据库实际情况调整
		Tree<MenuDO> t = BuildTree.build(trees);
		return t;
	}

	@Override
	public Tree<MenuDO> getTree() {
		List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
		List<MenuDO> menuDOs = menuMapper.selectByMap(new HashMap<>(16));
		for (MenuDO sysMenuDO : menuDOs) {
			Tree<MenuDO> tree = new Tree<MenuDO>();
			tree.setId(sysMenuDO.getMenuId().toString());
			tree.setParentId(sysMenuDO.getParentId().toString());
			tree.setText(sysMenuDO.getName());
			tree.setMenuType(sysMenuDO.getMenuType());
			trees.add(tree);
		}
		// 默认顶级菜单为０，根据数据库实际情况调整
		Tree<MenuDO> t = BuildTree.build(trees);
		return t;
	}

	@Override
	public Tree<MenuDO> getTree(Integer id) {
		// 根据roleId查询权限
		List<MenuDO> menus = menuMapper.selectByMap(new HashMap<String, Object>(16));
		RoleDO roleDO = roleDao.selectById(id);
		String roleRights = roleDO.getRights();
		List<Integer> tempParents = new ArrayList<>();
		for (MenuDO menu : menus) {
			boolean bl = RightsHelper.testRights(roleRights, menu.getParentId().toString());
			if (bl) {
				tempParents.add(menu.getParentId());
			}
		}
		List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
		List<MenuDO> menuDOs = menuMapper.selectByMap(new HashMap<String, Object>(16));
		for (MenuDO sysMenuDO : menuDOs) {
			Tree<MenuDO> tree = new Tree<MenuDO>();
			tree.setId(sysMenuDO.getMenuId().toString());
			tree.setParentId(sysMenuDO.getParentId().toString());
			tree.setText(sysMenuDO.getName());
			tree.setMenuType(sysMenuDO.getMenuType());
			Map<String, Object> state = new HashMap<>(16);
			Integer menuId = sysMenuDO.getMenuId();
			boolean bl = RightsHelper.testRights(roleRights, menuId.toString());
			if (bl && !tempParents.contains(menuId)) {
				state.put("selected", true);
			} else {
				state.put("selected", false);
			}
			tree.setState(state);
			trees.add(tree);
		}
		// 默认顶级菜单为０，根据数据库实际情况调整
		Tree<MenuDO> t = BuildTree.build(trees);
		return t;
	}

	@Override
	public Set<String> listPerms(Integer userId) {
		List<String> perms = getUserPerms(userId);
		Set<String> permsSet = new HashSet<>();
		for (String perm : perms) {
			if (StringUtils.isNotBlank(perm)) {
				permsSet.addAll(Arrays.asList(perm.trim().split(",")));
			}
		}
		return permsSet;
	}

	private List<String> getUserPerms(Integer userId){
		List<String> perms = new ArrayList<>();
		UserDO user = userDao.selectById(userId);
		RoleDO roleDO = roleDao.selectById(user.getRoleId());
		// 根据roleId查询权限
		if(roleDO != null){
			String roleRights = roleDO.getRights();
			List<MenuDO> menuDOs = menuMapper.selectByMap(new HashMap<String, Object>(16));
			for (MenuDO sysMenuDO : menuDOs) {
				Integer menuId = sysMenuDO.getMenuId();
				boolean bl = RightsHelper.testRights(roleRights, menuId.toString());
				if (bl) {
					perms.add(sysMenuDO.getPerms());
				}
			}
		}
		return perms;
	}


	@Override
	public List<Tree<MenuDO>> listMenuTree(Integer user_id) {
		UserDO user = userDao.selectById(user_id);
		RoleDO roleDO = roleDao.selectById(user.getRoleId());

		List<Tree<MenuDO>> trees = new ArrayList<>();
		// 根据roleId查询权限

		List<MenuDO> menus = menuMapper.selectByMap(new HashMap<String, Object>(16));
		if(roleDO != null){
			String roleRights = roleDO.getRights();
			QueryWrapper<MenuDO> qw = new QueryWrapper<>();
			qw.orderByAsc("order_num");
			qw.eq("show_type",1)
					.and(wrapper -> wrapper.eq("menu_type", 0).or().eq("menu_type", 1));
			List<MenuDO> menuDOs = menuMapper.selectList(qw);
//			List<MenuDO> menuDOs = menuMapper.listMenuByShow();
			for (MenuDO sysMenuDO : menuDOs) {
				Integer menuId = sysMenuDO.getMenuId();
				boolean bl = RightsHelper.testRights(roleRights, menuId.toString());
				if (bl) {
					Tree<MenuDO> tree = new Tree<>();
					tree.setId(sysMenuDO.getMenuId().toString());
					tree.setParentId(sysMenuDO.getParentId().toString());
					tree.setText(sysMenuDO.getName());
					tree.setMenuType(sysMenuDO.getMenuType());
					Map<String, Object> attributes = new HashMap<>(16);
					attributes.put("url", sysMenuDO.getUrl());
					attributes.put("icon", sysMenuDO.getIcon());
					tree.setAttributes(attributes);
					trees.add(tree);
				}
			}
		}

		// 默认顶级菜单为０，根据数据库实际情况调整
		List<Tree<MenuDO>> list = BuildTree.buildList(trees, "0");
		return list;
	}

}
